package com.dudu.service.impl;

import java.util.Calendar;

import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import com.dudu.access.EcpUtils;
import com.dudu.access.IMSTXUtils;
import com.dudu.access.ImsUtils;
import com.dudu.bean.MeetInfoBean;
import com.dudu.enumeration.AbilityTypeEnum;
import com.dudu.service.IConferenceAddService;
import com.dudu.service.ILogService;
import com.dudu.service.IMeetInfoService;
import com.dudu.utils.DateUtils;
import com.dudu.utils.PhoneUtils;
import com.dudu.utils.ProperyResource;
import com.huawei.mediax.webservice.types.InviteAllSubscriberResponseDocument;

import core.CoreDao;
import core.CoreDaoInvoke;

/**
 * 多方通话--加人
 * 
 * @author weidong
 * 
 */
public class ConferenceAddServiceImpl implements IConferenceAddService {
	// 用于查询数据用
	private CoreDao coreDao = CoreDaoInvoke.getInstance();
	private static final Logger log = core.util.Logger.getLogger(ConferenceAddServiceImpl.class.getSimpleName());
	// 用于记录相应接口调用的日志
	private ILogService logService = new LogService();

	/**
	 * 用于多方通话增加通话人
	 * 
	 * @param sessionId
	 *            会议标识
	 * @param calledNbr
	 *            增加号码
	 * @return
	 */
	@Override
	public JSONObject doAdd(String sessionId, String calledNbr) {
		// 用于最后返回值
		JSONObject object = new JSONObject();
		// 首先处理手机号码，将特殊字符等去除
		calledNbr = PhoneUtils.filterMobileNumber(calledNbr);
		try {
			// 判断sessionid与添加的号码是否为空，如果为空，则自动跳出
//			if (StringUtils.isBlank(sessionId) || StringUtils.isBlank(calledNbr)) {
//				object.put("result", "-1");
//				object.put("describe", "接口参数错误");
//				object.put("code", "0014");
//				return object;
//			}
			IMeetInfoService meetImsService = new MeetInfoServiceImpl();
			// 查询会议详情信息-根据会议sessionId-用于判断此通话的通话类型是哪个通道接入
			MeetInfoBean meetInfo = meetImsService.queryMeetImsBySessionId(coreDao, sessionId);
			String abilityType = "";
			if (meetInfo != null) {
				// 获取通话类型
				abilityType = meetInfo.getAbility_type();
				// 判断如果通道类型是IMS多方通话，则调用IMS多方通话接口
				if (AbilityTypeEnum.TALKSV2.getKey().equals(abilityType)) {
					// 调用接口 多方通话
					object = doAddTalksV2(sessionId, calledNbr);
				} else if (AbilityTypeEnum.ECPMEET.getKey().equals(abilityType)) {
					// 调用接口 ECP多方通话
					object = doAddECP(sessionId, calledNbr);
				} else if (AbilityTypeEnum.SCONFERENCE.getKey().equals(abilityType)) {
					// 调用接口 专业会议
					String soapSessionId = meetInfo.getRoom_id();
					// 判断如果没有取到soap相应的sessionId，则报异常
					if (soapSessionId == null || soapSessionId.equals("")) {
						object.put("result", "-1");
						object.put("errorMsg", "未找到相应的上级SOAPSessionId！");
						object.put("describe", "sessionId不存在");
						object.put("code", "0006");
					} else {
						object = doAddSOAP(soapSessionId, sessionId, calledNbr);
					}
				} else {
					object.put("result", "-1");
					object.put("errorMsg", "未配置对应通道！voice_type:" + abilityType);
					object.put("describe", "未配置线路");
					object.put("code", "0010");
				}
				// 如果增加人员成功，则修改会议人数等信息
				if ("0".equals(object.get("result"))) {
					manageCallerNumber(meetInfo, calledNbr);
				}
			} else {
				object.put("result", "-1");
				object.put("describe", "sessionId不存在");
				object.put("code", "0006");
			}
		} catch (Exception e) {
			object.put("result", "-1");
			object.put("errorMsg", "错误=" + e);
			object.put("describe", "多方通话添加参与人异常");
			object.put("code", "0305");
		}

		return object;
	}

	/**
	 * IMS智能多方通话增加通话人
	 * 
	 * @param sessionId
	 *            会议标识
	 * @param calledNbr
	 *            增加号码
	 * @return
	 */
	private JSONObject doAddTalksV2(String sessionId, String calledNbr) {
		// 用于后面返回值
		JSONObject object = new JSONObject();
		// 开始添加人
		try {
			// 调用IMS智能多方通话，增加通话人接口
			object = ImsUtils.talksV2Add(sessionId, calledNbr);
			if (!"0".equals(object.get("result"))) {
				object.put("result", "-1");
				object.put("describe", "多方通话添加参与人异常");
				object.put("code", "0305");
			}
		} catch (Exception e) {
			object.put("result", "-1");
			object.put("describe", "多方通话添加参与人异常");
			object.put("code", "0305");
		}
		return object;
	}

	/**
	 * IMS专业会议增加通话人
	 * 
	 * @param SOAPSessionId
	 *            会议标识
	 * @param conferenceId
	 *            会议室标识
	 * @param calledNbr
	 *            增加号码
	 * @return
	 */
	private JSONObject doAddSOAP(String SOAPSessionId, String conferenceId, String calledNbr) {
		// 最终返回的值
		JSONObject object = new JSONObject();
		try {
			// 用于记录发起会话所用时间
			// 开始时间的时间戳
			long begin = 0;
			// 结束时间的时间戳
			long end = 0;
			// 时间差值
			double during;
			// 通话发起时间
			String currentTime = DateUtils.getCurrentTime();
			String results = "";

			// 开始时间
			begin = Calendar.getInstance().getTimeInMillis();
			InviteAllSubscriberResponseDocument doc = IMSTXUtils.InviteAllSubscriber(SOAPSessionId, conferenceId,
					calledNbr);
			// 调用结束时间
			end = Calendar.getInstance().getTimeInMillis();
			if (doc != null && doc.getInviteAllSubscriberResponse() != null) {
				if (doc.getInviteAllSubscriberResponse().getCode() == 200) {
					results = "0";
					object.put("result", "0");
					object.put("describe", "IMS专业会议邀请人成功");
					object.put("code", "0000");
				} else {
					results = doc.getInviteAllSubscriberResponse().getCode() + "";
					object.put("result", doc.getInviteAllSubscriberResponse().getCode() + "");
					object.put("describe", "IMS专业会议邀请人失败");
					object.put("code", "0023");
				}
			} else {
				results = doc.getInviteAllSubscriberResponse().getCode() + "";
				object.put("result", doc.getInviteAllSubscriberResponse().getCode() + "");
				object.put("describe", "IMS专业会议邀请人失败");
				object.put("code", "0023");
			}
			// 发起通话的日志
			try {
				during = Double.valueOf((end - begin)) / 1000;
				// 获取发起通话的URL
				StringBuffer urlBuffer = new StringBuffer("IMS专业会议");
				// 拼相应的参数
				urlBuffer.append("?SOAPSessionId=");
				urlBuffer.append(SOAPSessionId);
				urlBuffer.append("&phone=");
				urlBuffer.append(calledNbr);
				logService.logIms(during, AbilityTypeEnum.SCONFERENCE.getKey() + "Add", urlBuffer.toString(), results,
						results, currentTime, "SOAP", "");
			} catch (Exception e) {
				log.info("------IMS专业会议中新增成员日志异常！----");
			}
		} catch (Exception e) {
			object.put("result", "-1");
			object.put("describe", "IMS专业会议添加参与人异常！");
			object.put("code", "0100");
			log.error("邀请参与人异常：" + e.getMessage());
		}
		return object;
	}

	/**
	 * ECP会议增加通话人
	 * 
	 * @param sessionId
	 *            会议标识
	 * @param calledNbr
	 *            增加号码
	 * @return
	 */
	private JSONObject doAddECP(String sessionId, String calledNbr) {
		// 最终返回的值
		JSONObject object = new JSONObject();
		try {
			// 用于记录发起会话所用时间
			// 开始时间的时间戳
			long begin = 0;
			// 结束时间的时间戳
			long end = 0;
			// 时间差值
			double during;
			// 通话发起时间
			String currentTime = DateUtils.getCurrentTime();
			// 开始时间
			begin = Calendar.getInstance().getTimeInMillis();
			// 邀请参与人
			String result = EcpUtils.inviteNumber(sessionId, calledNbr);
			// 结束时间
			end = Calendar.getInstance().getTimeInMillis();

			Document doc = DocumentHelper.parseText(result);
			Element root = doc.getRootElement();
			// 获取查询结果
			// 获取是否成功标识
			String results = root.elementTextTrim("result");

			// 发起通话的日志
			try {
				during = Double.valueOf((end - begin)) / 1000;
				// 获取发起通话的URL
				StringBuffer urlBuffer = new StringBuffer(ProperyResource.getEcp_Status_Url());
				// 拼相应的参数
				urlBuffer.append("?ConferenceIdentifier=");
				urlBuffer.append(sessionId);
				urlBuffer.append("&phone=");
				urlBuffer.append(calledNbr);
				logService.logIms(during, AbilityTypeEnum.ECPMEET.getKey() + "Add", urlBuffer.toString(), result,
						results, currentTime, "ECP", "");
			} catch (Exception e) {
				log.info("------ECP多方通话过程中新增成员日志异常！----" + e);
			}
			if (results.equals("1100")) {
				object.put("sessionId", sessionId);
				object.put("result", "0");
				object.put("describe", "添加参与人成功");
				object.put("code", "0000");
			} else {
				object.put("result", "-1");
				object.put("describe", "添加参与人错误：" + result);
				object.put("code", "0023");
			}
		} catch (Exception e) {
			object.put("result", "-1");
			object.put("describe", "添加参与人异常！");
			log.info("邀请参与人异常：" + e);
			object.put("code", "0100");
		}
		return object;
	}

	/**
	 * 更新会议记录中，通话人的总数量
	 * 
	 * @param meetInfo
	 *            会议实例
	 * @param calledNbr
	 *            新增被叫人
	 * @return
	 */
	public boolean manageCallerNumber(MeetInfoBean meetInfo, String calledNbr) {
		boolean isTrue = false;
		// 更新联系人数量
		String dbCallee = meetInfo.getCalled();
		StringBuffer sbPhone = new StringBuffer();
		// 判断被叫人是否为空
		if (StringUtils.isNotBlank(calledNbr)) {
			// 获取原通话号码
			sbPhone.append(dbCallee);
			// 获取新增加号码
			String newCallees[] = calledNbr.split(",");
			// 遍历新增号码
			for (int i = 0; i < newCallees.length; i++) {
				// 判断新增号码是否在老号码中
				if (!dbCallee.contains(newCallees[i])) {
					// 如果此号码不在老号码中，则将新号码拼入
					if (StringUtils.isNotBlank(sbPhone.toString())) {
						sbPhone.append(",");
						sbPhone.append(newCallees[i]);
					} else {
						sbPhone.append(newCallees[i]);
					}
				}
			}
			// 将号码存入会议实体类
			meetInfo.setCalled(sbPhone.toString());
			String afterPhone[] = sbPhone.toString().split(",");
			// 号码总数增加
			meetInfo.setTotal_amount(afterPhone.length + 1);

			try {
				// 存数相应数据
				IMeetInfoService meetInfoService = new MeetInfoServiceImpl();
				// 更新号码数量
				int upPhoneAcount = meetInfoService.updateMeetImsPhoneAndAcount(coreDao, meetInfo);
				if (upPhoneAcount > 0) {
					isTrue = true;
				}
			} catch (Throwable e) {
				e.printStackTrace();
			}
		}
		return isTrue;
	}
}
